package org.gzc.sort;

import java.util.Arrays;

/**
 * @Description: 归并排序
 * @Author: guozongchao
 * @Date: 2020/8/8 23:55
 */
public class MergeSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        int[] temp = new int[array.length];
        mergeSort(array, 0, array.length - 1,temp);
    }

    public void  mergeSort(int[] array, int left, int right,int[] temp) {

        if (left < right) {
            int mid = (left + right) / 2;
            //对左边分区进行递归
            mergeSort(array, left, mid, temp);
            //对右边分区进行递归
            mergeSort(array, mid + 1, right, temp);
            //合并左右两个有序列表
            merge(array, left, mid, right,temp);

        }
    }

    //合并
    public void merge(int[] array, int left, int mid, int right, int[] temp) {
        int i=left;  //左边有序序列的初始索引
        int j=mid+1;  //右边有序序列的初始索引
        int t=left;  //指向temp数组的当前索引

        //先把左右两边(有序)的数据按照规则填充到 temp 数组
        //直到左右两边的有序序列，有一边处理完毕为止
        while (i <= mid && j<=right) {
            //如果左边的有序序列的当前元素，小于 右边有序序列的当前元素，则将左边的当前元素放进temp,在进行i++
            if (array[i] < array[j]) {
                temp[t] = array[i];
                i++;
                t++;
            }else {  //反之，就将右边有序序列的当前元素放进temp
                temp[t] = array[j];
                j++;
                t++;
            }
        }

        //把有剩余数据的一边的数据依次全部填充到 temp
        while (i <= mid) {  //左边的有序序列还有剩余的元素，就全部填充到 temp
            temp[t] = array[i];
            i++;
            t++;
        }
        while (j <= right) {  //右边的有序序列还有剩余的元素，就全部填充到 temp
            temp[t] = array[j];
            j++;
            t++;
        }

        //将 temp 数组的元素拷贝到 array
        // 注意，并不是每次都拷贝所有
        for (int k=left;k<=right;k++) {
            array[k] = temp[k];
        }

    }
}
